﻿#region Copyright (c) Lokad 2010
// This code is released under the terms of the new BSD licence.
// URL: http://www.lokad.com/
#endregion
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Lokad.Monitoring.Persistence.Entities;
using Lokad.Monitoring.Persistence.Models;
using Lokad.Monitoring.Persistence.Serialization;
using NHibernate.Criterion;

namespace Lokad.Monitoring.Persistence.Repositories
{
    public class ResponseRepository : BaseRepository
    {
        public void Create(Endpoint endpoint, Rsm.RsmDocument rsm)
        {
            var stream = new MemoryStream();
            var serializer = new GzipPoxSerializer();
            serializer.Serialize(stream, rsm);

            var response = new Response
                               {
                                   Endpoint = endpoint,
                                   Retrieved = DateTime.UtcNow,
                                   Data = stream.ToArray()
                               };

            using (var trans = Session.BeginTransaction())
            {
                Session.Save(response);
                trans.Commit();
            }
        }

        public IList<RsmDocument> List(Endpoint endpoint, DateTime threshold)
        {
            return Session.CreateCriteria(typeof(Response))
                    .Add(Restrictions.Eq("Endpoint", endpoint))
                    .Add(Restrictions.Gt("Retrieved", threshold))
                    .List<Response>()
                    .OrderByDescending(r => r.Retrieved)
                    .ToList()
                    .Select(Convert)
                    .ToList();
        }

        public static RsmDocument Convert(Response response)
        {
            var stream = new MemoryStream(response.Data);
            stream.Position = 0;

            var serializer = new GzipPoxSerializer();
            var rsm = (Rsm.RsmDocument)serializer.Deserialize(stream, typeof (Rsm.RsmDocument));

            var doc = Convert(rsm);
            doc.Id = response.Id;
            doc.Retrieved = response.Retrieved;

            return doc;
        }

        public static RsmDocument Convert(Rsm.RsmDocument rsm)
        {
            return new RsmDocument
                       {
                           Indicators = rsm.Indicators.Select(
                               i => new Indicator
                                        {
                                            Name = i.Name,
                                            Tags = i.Tags,
                                            Updated = i.Updated,
                                            Value = i.Value,
                                            Link = i.Link,
                                        }).ToArray(),

                            Messages = rsm.Messages.Select(
                                m => new Message
                                         {
                                             Id = m.Id,
                                             Link = m.Link,
                                             Summary = m.Summary,
                                             Tags = m.Tags,
                                             Title = m.Title,
                                             Updated = m.Updated
                                         }
                            ).ToArray()
                       };
        }
    }
}
